#include "recovery/SubcodeStatus.h"

namespace recovery {

const char * SubcodeStatus::getSubcodeState(int subcode) const{
    static const char * subcodeMsg[static_cast<int>(SubcodeStatus::Subcode::kMaxSubcode)] = {
        " None ",
        " Invalid ",
        //TODO:
    };
    if(subcode < static_cast<int>(SubcodeStatus::Subcode::kMaxSubcode)){
        return subcodeMsg[subcode];
    }
    return nullptr;
}

std::string SubcodeStatus::what() const {
    if(code() == Code::kOK){
        return " OK ";
    }
    // [code] + state + [subcode];
    std::string out = Status::what();
    if(auto * subcodeMsg = getSubcodeState(_subcode); subcodeMsg != nullptr){
        return Status::what() + ":" + subcodeMsg;
    }
    return Status::what() + ": unknown subcode(" + std::to_string(static_cast<int>(_subcode)) +")";
}


Status SubcodeStatus::toStatus(const std::string_view & msg) const {
	if(isOK()){
		return *this;
	}

	Status s = Status::Subcode();

	int bufLen = 0;
	int slen = 0;
	if(state() != nullptr){
		bufLen += (slen =  std::strlen(state()));
	}
	int subLen = 0;
	auto * subcodeMsg = getSubcodeState(_subcode);
	if(subcodeMsg != nullptr){
		bufLen += (subLen = std::strlen(subcodeMsg));
	}

	char * buf = new char[bufLen+1];
	if(state() != nullptr){
		memcpy(buf, state(), slen);
	}
	if(subcodeMsg != nullptr){
		memcpy(buf + slen, subcodeMsg, subLen);
	}
	buf[bufLen] = '\0';

	s.state(buf);
    return s;
}


}// end of namespace recovery
